PHP魔术方法
@TOC
基本概念
PHP中把以两个下划线__开头的方法称为魔术方法,这些方法在PHP中充当了举足轻重的作用,它们服务于类和对象。
出现原因
PHP虽然是面向对象的语言,但是一些面向对象的标准并不完善,例如重载(函数或者方法有同样的名称,但是参数列表不相同的情形,这样的同名不同参数的函数或者方法之间,互相称之为重载函数或者方法),我们可以通过一些魔术方法弥补。
魔术方法详细解释
__construct(),类的构造函数
__destruct(),类的析构函数
__call(),在对象中调用一个不可访问方法时调用
__callStatic(),用静态方式中调用一个不可访问方法时调用
__get(),获得一个类的成员变量时调用
__set(),设置一个类的成员变量时调用
__sleep(),执行serialize()时,先会调用这个函数
__wakeup(),执行unserialize()时,先会调用这个函数
__toString(),类被当成字符串时的回应方法
__invoke(),调用函数的方式调用一个对象时的回应方法
__set_state(),调用var_export()导出类时,此静态方法会被调用。
__clone(),当对象复制完成时调用
一、__construct(),类的构造函数、__destruct(),类的析构函数
__construct 构造方法,当一个对象创建时调用此方法,而__destruct()是在一个对象销毁时调用,也就是PHP的gc机制
1 | <?php |
二、__call()、__callStatic()
当使用这些未定义的方法时就会进入这两个函数中。比如说我们调用$ a->b();这个方法,但其实在$a的类模板中并没有b()方法,这时就会进入__call()方法进行处理。__callStatic()则是通过静态调用时如果没有定义对应的方法,就进入到__callStatic()方法中,如A::b(),并没有定义b()方法,这时就进入了__callStatic()中进行处理。
三、__set()和__get()
__set()和__get()是操作不可访问的属性。注意,这里并不是指没有定义的属性,如果定义为private的属性也可以通过这两个魔术方法来进行定义,当然,也包括未定义的属性。
四、__sleep()和__wakeup()
当我们在执行serialize()和unserialize()时,会先调用这两个函数。例如我们在序列化一个对象时,这个对象有一个数据库链接,想要在反序列化中恢复链接状态,则可以通过重构这两个函数来实现链接的恢复,
这里需要注意的是,__sleep()需要返回一个数组,而这个数组对应着类中的属性名。通常来说,它们可以在序列化前进行数据清理工作,或者反序列化前进行数据的预处理工作。比如序列化前关闭数据库连接或者反序列化前打开数据库连接。
1 | <?php |
五、__toString()
__toString() 方法用于一个类被当成字符串时应怎样回应。例如 echo $obj; 应该显示些什么。此方法必须返回一个字符串,否则将出现致命错误。
1 | <?php |
六、__clone()
此方法在复制对象时被调用。我们知道在php中. $a为一个对象, $b= $a时。 $b为 $ a的引用。当$a发生改变时。 $b也会随之发生变化。那么为了使 $b不发生变化,我们需要用 $b=clone $a;
那么,当 $a在调用clone的时候,引擎会自动调用__clone()方法
七、Invoke
在php中这个方法用于,把对象当方法用的时候。此方法会被调用。
1 | class Invoke { |
七、__set_state()
了解这个方法前,需要先知道var_export()函数,var_export()和var_dump()类似,输出一个变量的字符串表示。他与var_dump的区别在于它的返回结果的是合法的
php代码.此代码可以被eval执行. 注意:此方法是一个静态方法,且在php5.1以上版本才支持。
绕过__wakeup
一、为什么要绕过__wakeup
举个例子
1 | <?php |
我们可知__wakeup将username的值设定为guest,题中需要为admin,而且根据__wake的特性,在反序列化中会提前执行,所以需要绕过
二、绕过方法:当成员属性数目大于实际数目时可绕过
题目来源:buuctf_php
在这里我们只介绍PHP内存马。
② 内存驻留Webshell通常会在php执行起来后,删除php文件本体。









































SQL注入万能密码:’or’=’or’

这是一道文件包含漏洞题,点击tips
/?file=php://filter/read=convert.base64-encode/resource=flag.php,出现base64形式,即可。

点击SECRET,
快速跳转,需要抓包
发现在secr3t.php
是文件包含漏洞,直接构造view-source: